package cn.hsa.fqz.monitor.service.impl;

import cn.hsa.fqz.common.utils.CHExecutor;
import cn.hsa.fqz.common.utils.page.BasePage;
import cn.hsa.fqz.common.utils.page.PageData;
import cn.hsa.fqz.monitor.controller.vo.*;
import cn.hsa.fqz.monitor.dao.*;
import cn.hsa.fqz.monitor.entity.*;
import cn.hsa.fqz.monitor.enums.OperatorEnum;
import cn.hsa.fqz.monitor.service.MonitorService;
import cn.hsa.fqz.monitor.service.dto.MonitorExecuteSqlDTO;
import cn.hsa.fqz.monitor.service.dto.TMonitorUserSqlConditionDTO;
import cn.hsa.fqz.task.service.IDataFluxService;
import cn.hsa.fqz.task.service.dto.LoginUserDTO;
import cn.hsa.fqz.task.service.dto.TTagSubjectDTO;
import cn.hsa.fqz.util.Constants;
import cn.hsa.fqz.util.DataUtils;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description TODO
 * @ClassName TTaskTagMonitorServiceImpl
 * @Author Liu.Jun
 * @Create 2023-10-20 15:37
 * @Version 1.0.0
 */
@Service
@Slf4j
public class MonitorServiceImpl implements MonitorService {

    @Value("${zmjk.monitor.table.prefix}")
    private String tablePrefix;

    @Autowired
    private IDataFluxService dataFluxService;

    @Autowired
    private TMonitorEntityDimensionPropertiesMapper tMonitorEntityDimensionPropertiesMapper;

    @Autowired
    private TMonitorEntityMapper tMonitorEntityMapper;

    @Autowired
    private TMonitorUserSubjectMapper tMonitorUserSubjectMapper;

    @Autowired
    private TMonitorEntityBasicMapper tMonitorEntityBasicMapper;

    @Autowired
    private TMonitorEntityDimensionMapper tMonitorEntityDimensionMapper;

    @Autowired
    private TMonitorEntityPropertiesMapper tMonitorEntityPropertiesMapper;

    @Autowired
    private TMonitorColumnsMapper tMonitorColumnsMapper;

    @Autowired
    private TMonitorEntityExecuteSqlMapper tMonitorEntityExecuteSqlMapper;

    @Autowired
    private TMonitorDimensionMapper tMonitorDimensionMapper;

    @Autowired
    private TMonitorUserSqlConditionMapper tMonitorUserSqlConditionMapper;

    @Autowired
    private TMonitorEntityExecuteSqlPropertiesMapper tMonitorEntityExecuteSqlPropertiesMapper;

    @Override
    public List<MonitorTagMinVO> getTagsByEnityCode(String entityCode, List<String> dimension,String sqlTableName) {
        List<MonitorTagMinVO> result = Lists.newArrayList();
        if(CollectionUtil.isNotEmpty(dimension)){
            String tableName = getTableNameByEntityCodeAndDimensions(entityCode, dimension);
            List<TMonitorEntityDimensionProperties> dimensions = tMonitorEntityDimensionPropertiesMapper.getEntityPropertiesByTableNameAndCategory(tableName,"3");
            for (TMonitorEntityDimensionProperties prop: dimensions) {
                MonitorTagMinVO vo = new MonitorTagMinVO();
                vo.setLabel(prop.getPropName());
                vo.setRadios(prop.getIsDefault());
                vo.setValue(prop.getPropCode());
                result.add(vo);
            }
        }else if(StringUtils.isNotEmpty(sqlTableName)){
            List<TMonitorEntityExecuteSqlProperties> properties = tMonitorEntityExecuteSqlPropertiesMapper.selectByTableNameAndCategory(sqlTableName, "3");
            for (TMonitorEntityExecuteSqlProperties prop: properties) {
                MonitorTagMinVO vo = new MonitorTagMinVO();
                vo.setLabel(prop.getPropName());
                vo.setRadios(prop.getIsDefault());
                vo.setValue(prop.getPropCode());
                result.add(vo);
            }
        }else{
            List<TMonitorEntityProperties> properties = tMonitorEntityPropertiesMapper.selectByEntityCodeAndCategory(entityCode,"3");
            for (TMonitorEntityProperties prop: properties) {
                MonitorTagMinVO vo = new MonitorTagMinVO();
                vo.setLabel(prop.getPropName());
                vo.setRadios(prop.getIsDefault());
                vo.setValue(prop.getPropCode());
                result.add(vo);
            }
        }
        return result;
    }

    private String getTableNameByEntityCodeAndDimensions(String entityCode,List<String> dimension){
        List<TMonitorEntityDimension> entityDimensions = tMonitorEntityDimensionMapper.selectByEntityCode(entityCode);
        for (TMonitorEntityDimension di:entityDimensions) {
            String[] diArr = di.getDimensionCodeArr().split(Constants.TABLE_SEP);
            List<String> diLs = Arrays.asList(diArr);
            Collection<String> col = CollectionUtils.subtract(dimension, diLs);
            if(CollectionUtil.isEmpty(col)){
                return di.getTableName();
            }
        }
        return "";
    }

    @Override
    public List<TTagSubjectDTO> getTagSubject(String host,Integer port,String passwd,TMonitorSubjectVO vo,String account) {
        List<TTagSubjectDTO> result = Lists.newArrayList();
        TMonitorEntityBasic basic = tMonitorEntityBasicMapper.selectByEntityCode(vo.getEntityCode());
        StringBuffer buffer = new StringBuffer("select ");
        buffer.append(basic.getCodeColumnName()).append(" subjectCode,").append(basic.getNameColumnName()).append(" subjectName,").append(basic.getNameColumnName()).append(" proviceName from ")
                .append( basic.getBasicTableName()).append(" where 1=1 ");
        if(StringUtils.isNotEmpty(vo.getSubjectName())){
            buffer.append(" and ").append(basic.getNameColumnName()).append(" like '%%%s%%'");
        }
        if(StringUtils.isNotEmpty(vo.getAdmdvs())){
            buffer.append(" and admdvs ").append(" = '").append(vo.getAdmdvs()).append("'");
        }
        String sql = String.format(buffer.toString(), vo.getSubjectName());
        log.info("执行ck-sql: " + sql);
        List<Map<String, Object>> mapList = dataFluxService.getTaskSqlExecuteList(host,port,passwd, sql);
        List<TMonitorUserSubject> userSubjects = tMonitorUserSubjectMapper.selectByUserAcctAndEntityCode(vo.getEntityCode(),account);
        if(CollectionUtil.isNotEmpty(mapList)){
            for (Map<String,Object> mmp:mapList) {
                TTagSubjectDTO dto = BeanUtil.toBean(mmp, TTagSubjectDTO.class);
                dto.setStatus(1);
                Optional<TMonitorUserSubject> optional = userSubjects.stream().filter(e ->e.getSubjectCode().equals(dto.getSubjectCode())).findFirst();
                dto.setOperation(optional.isPresent());
                result.add(dto);
            }
        }
        return result;
    }

    private String getAdmdvsField(String tableName,String entityCode,boolean isDimension){
        String field = "";
        if(isDimension){
            field = tMonitorEntityDimensionPropertiesMapper.selectAdmdvsPropCodesByTableName(tableName);
        }else{
            field = tMonitorEntityPropertiesMapper.selectAdmdvsPropCodesByEntityCode(entityCode);
        }
        return field;
    }

    private String genFieldsSql(String tableName,List<String> tagList,String entityCode,boolean isDimension,boolean isExecuteSql) {
        List<String> fields = Lists.newArrayList();
        if(isDimension){
            fields = tMonitorEntityDimensionPropertiesMapper.selectPropCodesByTableNameAndCodes(tableName, tagList);
        }else if(isExecuteSql){
            fields = tMonitorEntityExecuteSqlPropertiesMapper.selectPropCodesByTableNameAndCodes(tableName,tagList);
        }else{
            fields = tMonitorEntityPropertiesMapper.selectAllPropCodeByEntityAndCodes(entityCode,tagList);
        }
        StringBuffer buffer = new StringBuffer();
        for (String str:fields) {
            buffer.append(str).append(",");
        }
        return buffer.substring(0,buffer.length()-1);
    }

    private String genWhereSql(String tableName,String host,Integer port,String pwd,TagMonitorQueryVO vo,boolean isCurrentUser,String admdvsField) throws ParseException {
        TMonitorEntity entity = tMonitorEntityMapper.getEntityByCode(vo.getEntityCode());
        String sql = "select * from " + tableName + " limit 1";
        List<String> columns = dataFluxService.getColumns(host, port, pwd, sql);
        StringBuffer buffer = new StringBuffer();
        buffer.append(" and timetype = '").append(vo.getQueryType()).append("' ");
        if(StringUtils.isNotEmpty(vo.getYear())&& StringUtils.isEmpty(vo.getWeek())&& StringUtils.isEmpty(vo.getMonth())){
            buffer.append(" and substr(setl_time,1,4) = '").append(vo.getYear()).append("'");
        }else if(StringUtils.isNotEmpty(vo.getYear())&& StringUtils.isNotEmpty(vo.getWeek())&& StringUtils.isEmpty(vo.getMonth())){
            String queryTime = vo.getYear() + "-" + DataUtils.getWeekendByDateTime(vo.getWeek());
            buffer.append(" and setl_time = '").append(queryTime).append("'");
        }else if(StringUtils.isNotEmpty(vo.getYear())&& StringUtils.isEmpty(vo.getWeek())&& StringUtils.isNotEmpty(vo.getMonth())){
            buffer.append(" and setl_time = '").append(vo.getYear()).append("-").append(vo.getMonth()).append("'");
        }
        if(StringUtils.isNotEmpty(vo.getBeginTime())){
            buffer.append(" and setl_time >= '").append(vo.getBeginTime()).append("' ");
        }
        if(StringUtils.isNotEmpty(vo.getEndTime())){
            buffer.append(" and setl_time <= '").append(vo.getEndTime()).append("' ");
        }
        if(CollectionUtil.isNotEmpty(vo.getSubjectCode())){
            List<String> subjectCodes = vo.getSubjectCode();
            StringBuffer buffer1 = new StringBuffer();
            for (String subjectCode: subjectCodes) {
                buffer1.append("'").append(subjectCode).append("',");
            }
            buffer.append(" and ").append(entity.getSerialField()).append(" in (").append(buffer1.substring(0,buffer1.length()-1)).append(") ");
        }else if(isCurrentUser){
            buffer.append("and 1=2");
        }
        Map<String,Object> mmp = vo.getParams();
        if(CollectionUtil.isNotEmpty(mmp)){
            for (Map.Entry<String,Object> entry: mmp.entrySet()) {
                String column = entry.getKey().toLowerCase();
                Object value = entry.getValue();
                if(value != null && columns.contains(column)){
                    if(value instanceof ArrayList){
                        ArrayList<String> strs = (ArrayList) value;
                        buffer.append(" and "+column+" in( ");
                        StringBuffer columnString = new StringBuffer();
                        for (String str:strs) {
                            columnString.append("'").append(str).append("',");
                        }
                        buffer.append(columnString.substring(0, columnString.length() - 1)).append(")");
                    }else {
                        String str = String.valueOf(entry.getValue());
                        if(StringUtils.isNotEmpty(str)){
                            buffer.append(" and "+column+" = '" + str + "'");
                        }
                    }
                }
            }
        }
        List<ConditionVO> conditionVOS = vo.getConditions();
        if(CollectionUtil.isNotEmpty(conditionVOS)){
            StringBuffer buffer1 = new StringBuffer();
            for (ConditionVO con:conditionVOS) {
                if(con.getOperator().equals(OperatorEnum.between.toString())){
                    String[] values = con.getValue().split(",");
                    buffer1.append(Constants.BLANK_CHAR).append(con.getConnector()).append(Constants.BLANK_CHAR).append("toFloat64(").append(con.getField()).append(") ")
                            .append(" between ").append("toFloat64('").append(values[0]).append("')").append(" and ").append("toFloat64('").append(values[1]).append("')").append(Constants.BLANK_CHAR);
                }else{
                    buffer1.append(Constants.BLANK_CHAR).append(con.getConnector()).append(Constants.BLANK_CHAR).append("toFloat64(").append(con.getField()).append(") ")
                            .append(con.getOperator()).append(" toFloat64('").append(con.getValue()).append("')").append(Constants.BLANK_CHAR);
                }
            }
            buffer.append(buffer1.toString());
        }
        if(StringUtils.isNotEmpty(admdvsField)){
            String admdvsWhereSql = genAdmdvsWhereSql(vo, admdvsField);
            buffer.append(admdvsWhereSql);
        }
        if(entity == null){
            buffer.append(" order by setl_time ");
        }else if(entity != null && vo.getExecute() != null){
            buffer.append(" order by "+admdvsField+",setl_time ");
        }else{
            buffer.append(" order by "+entity.getSerialField()+",setl_time ");
        }

        return buffer.toString();
    }

    private String genAdmdvsWhereSql(TagMonitorQueryVO vo,String key){
        StringBuffer buffer = new StringBuffer();
        String value = vo.getAdmdvs();
        if(StringUtils.isNotEmpty(vo.getAdmdvsType())){
            if(vo.getAdmdvsType().equals("0")){  //国家数据查询
                buffer.append(" and "+key+" ='100000'");
            }else if(vo.getAdmdvsType().equals("1")){
                buffer.append(" and "+key+" in (select distinct admdvs from v_fqz_dm_admdvs where prnt_admdvs='100000')");
            }else {  //省和地市查询
                buffer.append(" and "+key+" in (select distinct admdvs from v_fqz_dm_admdvs where prnt_admdvs='"+value+"')");
            }
        }
        return buffer.toString();
    };

    private String genTableName(TagMonitorQueryVO vo){
        StringBuffer buffer = new StringBuffer(tablePrefix);
        if(CollectionUtil.isNotEmpty(vo.getDimensions())){
            List<TMonitorEntityDimension> dimensions = tMonitorEntityDimensionMapper.selectByEntityCode(vo.getEntityCode());
            for (TMonitorEntityDimension dimension: dimensions) {
                String[] dimensionArr = dimension.getDimensionCodeArr().split(Constants.TABLE_SEP);
                List<String> source = ObjectUtil.clone(Arrays.asList(dimensionArr));
                //集合取差集，当前维度一样，取对应的实体维度表名
                List<String> target = vo.getDimensions();
               /* List<String> source =  Arrays.asList(dimensionArr);
                Collection<String> target = ObjectUtil.clone(vo.getDimensions());
                Collection tmp = CollectionUtils.subtract(source, target);
                if(CollectionUtil.isEmpty(tmp)){
                    return dimension.getTableName();
                }*/
                source.sort(Comparator.comparing(String::hashCode));
                target.sort(Comparator.comparing(String::hashCode));
                if(source.toString().equals(target.toString())){
                    return dimension.getTableName();
                }
            }
        }else{
            buffer.append(vo.getBussCode()).append(Constants.TABLE_SEP).append(vo.getEntityCode());
        }
        return buffer.toString();
    }

    private String genModelSelectSql(String entityCode,String queryType,boolean isSingle,String tag) {
        StringBuffer buffer = null;
        if(isSingle){
            buffer = new StringBuffer("select ");
            buffer.append(StringUtils.isNotEmpty(tag)?tag:"medfee_sumamt").append(" from ");
        }else{
            buffer = new StringBuffer(("select * from "));
        }
        String tableName = "";
        buffer.append(tableName);
        return buffer.toString();
    }

    private String parseColumns(List<String> props) {
        StringBuffer sb = new StringBuffer();
        for (String prop: props ) {
            sb.append(prop).append(",");
        }
        return sb.toString();
    }

    private String genFullSql(String selectSql,String tableName,String fields,String whereSql){
        if(StringUtils.isEmpty(selectSql)){
            StringBuffer buffer = new StringBuffer("select ");
            buffer.append(fields).append(" from ").append(tableName).append(" where 1=1 ").append(whereSql);
            return buffer.toString();
        }else{
            return "select "+fields+ " from ("+selectSql+") where 1=1 " + whereSql;
        }
    }

    @Override
    public PageData<Map<String, Object>> getPageResultWihSqlByCondition(String host, Integer port,String passwd, TagMonitorQueryVO vo) throws ParseException {
        String tableName = genTableName(vo);
        boolean flag = null!=vo.getExecute();
        String fields = genFieldsSql(tableName, vo.getTagList(), vo.getEntityCode(), CollectionUtil.isNotEmpty(vo.getDimensions()),flag);
        String admdvsFields = getAdmdvsField(tableName, vo.getEntityCode(), CollectionUtil.isNotEmpty(vo.getDimensions()));
        String whereSql = genWhereSql(tableName,host,port,passwd,vo,false,admdvsFields);
        String sql = genFullSql(null,tableName, fields, whereSql);
        log.info("执行ck-sql: " + sql);
        PageData<Map<String, Object>> result = dataFluxService.getTaskSqlExecutePageResult(host,port,passwd, sql,vo.getPage().getPageNum(),vo.getPage().getPageSize());
        List<Map<String,Object>> dataLs = Lists.newArrayList();
        for (Map<String,Object> map:result.getRows()) {
            Map<String,Object> mmp = Maps.newTreeMap();
            for (Map.Entry<String,Object> entry:map.entrySet()) {
                //String key = translateLabel(entry.getKey(), columns);
                String key = entry.getKey();
                mmp.put(key, entry.getValue());
            }
            dataLs.add(mmp);
        }
        result.setRows(dataLs);
        return result;
    }

    @Override
    public List<TMonitorDimension> getDimensionsByEntityCode(String entityCode) {
        List<TMonitorDimension> result = tMonitorDimensionMapper.selectByEntityCode(entityCode);
        result.forEach( e -> e.setKeyword(e.getKeyword().toUpperCase()));
        return result;
    }

    @Override
    public Object executeSql(LoginUserDTO loginUser, String ckHost, Integer ckPort, String ckPasswd, MonitorExecuteSqlDTO execute, BasePage page) throws ParseException {
        TMonitorEntityExecuteSql entityExecuteSql = execute.getExecute();
        String executeSQL = entityExecuteSql.getExecSql();
        StringBuffer sql = new StringBuffer("select * from (");
        sql.append(executeSQL).append(") limit 1");
        List<String> columns = CHExecutor.getColumnsBySql(ckHost,ckPort,ckPasswd,sql.toString());
        Map<String,Object> params = execute.getParams();
        StringBuffer buffer = new StringBuffer();
        if(execute.getExecute().getIsFilter().intValue() == 1){
            TagMonitorQueryVO vo = new TagMonitorQueryVO();
            BeanUtils.copyProperties(execute,vo);
            String whereSql = genWhereSql(entityExecuteSql.getTableName(),ckHost,ckPort,ckPasswd, vo,false,entityExecuteSql.getAdmdvsColumn());
            buffer.append(Constants.BLANK_CHAR).append(whereSql);
        }

        executeSQL = "select * from ("+executeSQL+")"+(executeSQL.indexOf("where")>-1?" ":" where 1=1 ")+buffer.toString();
        log.info("执行ck-sql: " + executeSQL);
        List<String> rsColumns = dataFluxService.getColumns(ckHost, ckPort, ckPasswd, executeSQL);
        String fields = executeSQL.substring(executeSQL.indexOf("select")+6, executeSQL.indexOf("from"));
        List<TMonitorColumns> columnList = tMonitorColumnsMapper.getAllColumns();
        PageData<Map<String, Object>> pageData = dataFluxService.getTaskSqlExecutePageResult(ckHost,ckPort,ckPasswd, executeSQL,execute.getPage().getPageNum(),execute.getPage().getPageSize());
        List<Map<String,Object>> dataList = pageData.getRows();
        List<Map<String,Object>> rows = Lists.newArrayList();
        Map<String,Object> map = Maps.newHashMap();
        if(CollectionUtil.isNotEmpty(dataList)){
            List<Map<String,String>> headResultList = Lists.newArrayList();
            List<List<Map<String,Object>>> dataResultList = Lists.newArrayList();
            rsColumns.stream().forEach( e -> {
                Map<String, String> mp = new HashMap<>();
                mp.put("label", translateLabel(e.trim(),columnList));
                headResultList.add(mp);
            });
            map.put("headData", headResultList);
            for (Map<String, Object> mmp: dataList) {
                List<Map<String,Object>> tmpList = Lists.newArrayList();
                for (String column:rsColumns) {
                    Map<String,Object> mp = new HashMap<>();
                    mp.put("value", mmp.get(column));
                    mp.put(column, mmp.get(column));
                    mp.put("status",1);  //
                    tmpList.add(mp);
                }
                dataResultList.add(tmpList);
            }
            map.put("tableData", dataResultList);
        }
        rows.add(map);
        pageData.setRows(rows);
        return pageData;
    }

    @Override
    public String getDefaultTag(TagMonitorQueryVO vo) {
        String tableName = genTableName(vo);
        String defaultTag = "";
        if(CollectionUtil.isEmpty(vo.getDimensions())){
            defaultTag = tMonitorEntityPropertiesMapper.selectDefaultPropByEntityCode(vo.getEntityCode());
        }else{
            defaultTag = tMonitorEntityDimensionPropertiesMapper.selectDefaultPropByTableName(tableName);
        }
        return defaultTag;
    }

    @Override
    public Boolean addUserSqlCondition(MonitorUserSqlConditionVO vo, LoginUserDTO dto) {
        List<ConditionVO> vos = vo.getConditions();
        if(CollectionUtil.isNotEmpty(vos)){
            for (ConditionVO cvo:vos) {
                TMonitorUserSqlCondition con = new TMonitorUserSqlCondition();
                con.setEntityCode(vo.getEntityCode());
                con.setExecSqlId(vo.getExecSqlId());
                con.setUserAcct(dto.getAccount());
                con.setUserAcctId(dto.getUid());
                con.setFieldColumn(cvo.getField());
                String conditionJson = JSON.toJSONString(cvo);
                con.setConditionJson(conditionJson);
                tMonitorUserSqlConditionMapper.deleteByEntityCodeAndUserAcctAndField(vo.getEntityCode(),dto.getAccount(),cvo.getField());
                tMonitorUserSqlConditionMapper.insertSelective(con);
            }
        }
        return true;
    }

    @Override
    public TMonitorUserSqlConditionDTO getCurrentUserConditions(String userAcct, String entityCode) {
        List<TMonitorUserSqlCondition> conditions = tMonitorUserSqlConditionMapper.selectByUserAcctAndEntityCode(userAcct,entityCode);
        List<ConditionVO> vos = Lists.newArrayList();
        TMonitorUserSqlConditionDTO dto = new TMonitorUserSqlConditionDTO();
        List<TMonitorColumns> columns = tMonitorColumnsMapper.getAllColumns();
        if(CollectionUtil.isNotEmpty(conditions)){
            for (TMonitorUserSqlCondition c:conditions) {
                BeanUtil.copyProperties(c, dto);
                String json = c.getConditionJson();
                ConditionVO cvo = JSON.parseObject(json, ConditionVO.class);
                Optional<TMonitorColumns> optional = columns.stream().filter( co -> co.getColumnLabel().equals(cvo.getField())).findFirst();
                if(optional.isPresent()){
                    TMonitorColumns columns1 = optional.get();
                    cvo.setField(columns1.getColumnName());
                    cvo.setFieldLabel(columns1.getColumnLabel());
                }else {
                    cvo.setFieldLabel(cvo.getField());
                }
                cvo.setId(c.getId());
                vos.add(cvo);
            }
        }
        dto.setConditionVOS(vos);
        return dto;
    }

    @Override
    public Boolean deleteCurrentUserConditions(Integer conditionId) {
        tMonitorUserSqlConditionMapper.deleteByPrimaryKey(conditionId);
        return true;
    }

    @Override
    public List<MonitorTagMinVO> getDimensionPropertiesByEnityCode(TagQueryVO queryVO) {
        String entityCode = queryVO.getEntityCode();
        List<String> dimension = queryVO.getDimensions();
        List<MonitorTagMinVO> result = Lists.newArrayList();
        if(CollectionUtil.isNotEmpty(dimension)){
            String tableName = getTableNameByEntityCodeAndDimensions(entityCode, dimension);
            List<TMonitorEntityDimensionProperties> dimensions = tMonitorEntityDimensionPropertiesMapper.getEntityPropertiesByTableNameAndCategory(tableName,"2");
            for (TMonitorEntityDimensionProperties prop: dimensions) {
                MonitorTagMinVO vo = new MonitorTagMinVO();
                vo.setLabel(prop.getPropName());
                vo.setRadios(prop.getIsDefault());
                vo.setValue(prop.getPropCode());
                result.add(vo);
            }
        }else if(StringUtils.isNotEmpty(queryVO.getTableName())){
            List<TMonitorEntityExecuteSqlProperties> dimensions = tMonitorEntityExecuteSqlPropertiesMapper.selectByTableNameAndCategory(queryVO.getTableName(), "2");
            for (TMonitorEntityExecuteSqlProperties prop: dimensions) {
                MonitorTagMinVO vo = new MonitorTagMinVO();
                vo.setLabel(prop.getPropName());
                vo.setRadios(prop.getIsDefault());
                vo.setValue(prop.getPropCode());
                result.add(vo);
            }
        }else{
            List<TMonitorEntityProperties> properties = tMonitorEntityPropertiesMapper.selectByEntityCodeAndCategory(entityCode,"2");
            for (TMonitorEntityProperties prop: properties) {
                MonitorTagMinVO vo = new MonitorTagMinVO();
                vo.setLabel(prop.getPropName());
                vo.setRadios(prop.getIsDefault());
                vo.setValue(prop.getPropCode());
                result.add(vo);
            }
        }
        return result;
    }

    @Override
    public List<Map<String, Object>> getResultWihSqlByCondition(String host,Integer port,String passwd, TagMonitorQueryVO vo) throws ParseException {
        String tableName = genTableName(vo);
        boolean flag = null!=vo.getExecute();
        String fields = genFieldsSql(tableName, vo.getTagList(), vo.getEntityCode(), CollectionUtil.isNotEmpty(vo.getDimensions()),flag);
        String admdvsFields = getAdmdvsField(tableName, vo.getEntityCode(), CollectionUtil.isNotEmpty(vo.getDimensions()));
        String whereSql = genWhereSql(tableName,host,port,passwd,vo,false,admdvsFields);
        String sql = genFullSql(null,tableName, fields, whereSql);
        log.info("执行ck-sql: " + sql);
        List<Map<String, Object>> result = dataFluxService.getTaskSqlExecuteList(host,port,passwd, sql);
        return result;
    }

    @Override
    public List<Map<String, Object>> getStatisticResultWihSqlByCondition(String host,Integer port,String passwd, TagMonitorQueryVO vo) throws ParseException {
        TMonitorEntityExecuteSql executeSql = vo.getExecute();
        String tableName = "";
        if(null == executeSql){
            tableName = genTableName(vo);
        }else{
            tableName = executeSql.getTableName();
        }
        TMonitorEntity entity = tMonitorEntityMapper.getEntityByCode(vo.getEntityCode());
        boolean flag = null!=vo.getExecute();
        String fields = genFieldsSql(tableName, vo.getTagList(), vo.getEntityCode(), CollectionUtil.isNotEmpty(vo.getDimensions()),flag);
        String admdvsFields = "";
        if(null == vo.getExecute()){
            admdvsFields = getAdmdvsField(tableName, vo.getEntityCode(), CollectionUtil.isNotEmpty(vo.getDimensions()));
        }else{
            admdvsFields = vo.getExecute().getAdmdvsColumn();
        }
        String whereSql = genWhereSql(tableName,host,port,passwd,vo,false,admdvsFields);
        String sql = "";
        if(null == executeSql){
            sql = genFullSql(null,tableName, fields, whereSql);
        }else{
            String selectSql = executeSql.getExecSql();
            sql = genFullSql(selectSql,tableName, fields, whereSql);
        }
        log.info("执行ck-sql: " + sql);
        List<Map<String, Object>> result = dataFluxService.getTaskSqlExecuteList(host,port,passwd, sql);
        Map<String,List<Map<String,Object>>> mmp =result.stream().collect(Collectors.groupingBy(e -> e.get(entity.getGroupbyField()).toString()));
        List<Map<String,Object>> data = Lists.newArrayList();
        for (Map.Entry<String,List<Map<String,Object>>> entry:mmp.entrySet()) {
            Map<String,Object> mp = Maps.newTreeMap();
            mp.put("name", entry.getKey());
            List<Map<String,Object>> val = entry.getValue();
            List dataLs = Lists.newArrayList();
            List rqLs = Lists.newArrayList();
            for (Map<String,Object> map:val) {
                rqLs.add(map.get("setl_time"));
                dataLs.add(map.get(vo.getTagList().get(0)));
            }
            mp.put("data", dataLs);
            mp.put("rq", rqLs);
            data.add(mp);
        }
        return data;
    }

    @Override
    public Boolean addCurrentUserPreview(MonitorUserSubjectVO vo) {
        if(vo.getOperation()){
            if(CollectionUtil.isNotEmpty(vo.getSubjectCode())){
                List<String> subjectCodes = vo.getSubjectCode();
                for (String subjectCode:subjectCodes) {
                    TMonitorUserSubject po = new TMonitorUserSubject();
                    po.setUserAcct(vo.getUserAcct());
                    po.setUserAcctId(vo.getUserAcctId());
                    po.setEntityCode(vo.getEntityCode());
                    po.setSubjectCode(subjectCode);
                    tMonitorUserSubjectMapper.insertSelective(po);
                }
                return true;
            }
        }else{
            if(CollectionUtil.isNotEmpty(vo.getSubjectCode())){
                List<String> subjectCodes = vo.getSubjectCode();
                for (String subjectCode:subjectCodes) {
                    tMonitorUserSubjectMapper.deleteByEntityCodeAndSubjectAndUserAcct(vo.getEntityCode(),subjectCode,vo.getUserAcct());
                }
                return true;
            }
        }
        return false;
    }

    @Override
    public List<String> getSubjectCodeByAccountAndEntityCode(String account, String entityCode) {
        List<TMonitorUserSubject> subjects = tMonitorUserSubjectMapper.selectByUserAcctAndEntityCode(entityCode, account);
        return subjects.stream().map(TMonitorUserSubject::getSubjectCode).collect(Collectors.toList());
    }

    @Override
    public List<TMonitorEntityExecuteSql> getSqlExecuteBySourceEntityCode(String entityCode) {
        return tMonitorEntityExecuteSqlMapper.selectBySourceEntityCode(entityCode);
    }

    @Override
    public List<TMonitorEntityExecuteSql> getSqlExecuteByTargetEntityCode(String entityCode) {
        return tMonitorEntityExecuteSqlMapper.selectByTargetEntityCode(entityCode);
    }

    @Override
    public PageData<Map<String, Object>> getModelResultWihSqlByCondition(String host, Integer port, String passwd, TagMonitorQueryVO vo) throws ParseException {
        String selectSql = genModelSelectSql(vo.getModelCode(),vo.getQueryType(),false,null);
        String whereSql = genWhereSql("",host,port,passwd,vo,false,"admdvs_code");
        String sql = selectSql + " " + whereSql;
        log.info("执行ck-sql: " + sql);
        PageData<Map<String, Object>> result = dataFluxService.getTaskSqlExecutePageResult(host,port,passwd, sql,vo.getPage().getPageNum(),vo.getPage().getPageSize());
        return result;
    }

    @Override
    public List<Map<String,Object>> getSingleModelResultWihSqlByCondition(String host, Integer port, String passwd, TagMonitorQueryVO vo) throws ParseException {
        String tag = vo.getTagList().get(0);
        String selectSql = genModelSelectSql(vo.getModelCode(),vo.getQueryType(),true,tag);
        String whereSql = genWhereSql("",host,port,passwd,vo,false,"admdvs_code");
        String sql = selectSql + " " + whereSql;
        log.info("执行ck-sql: " + sql);
        List<Map<String, Object>> result = dataFluxService.getTaskSqlExecuteList(host,port,passwd, sql);
        return result;
    }

    @Override
    public PageData<Map<String, Object>> getMapPageResultWihSqlByCondition(String host, Integer port, String passwd, TagMonitorQueryVO vo) throws ParseException {
        List<TMonitorColumns> columns = tMonitorColumnsMapper.getAllColumns();
        String tableName = genTableName(vo);
        boolean flag = null!=vo.getExecute();
        String fields = genFieldsSql(tableName, vo.getTagList(), vo.getEntityCode(), CollectionUtil.isNotEmpty(vo.getDimensions()),flag);
        String admdvsFields = getAdmdvsField(tableName, vo.getEntityCode(), CollectionUtil.isNotEmpty(vo.getDimensions()));
        String whereSql = genWhereSql(tableName,host,port,passwd,vo,false,admdvsFields);
        String sql = genFullSql(null,tableName, fields, whereSql);
        log.info("执行ck-sql: " + sql);
        PageData<Map<String, Object>> pageData = dataFluxService.getTaskSqlExecutePageResult(host,port,passwd, sql,vo.getPage().getPageNum(),vo.getPage().getPageSize());
        List<Map<String,Object>> dataList = pageData.getRows();
        List<Map<String,Object>> rows = Lists.newArrayList();
        Map<String,Object> map = Maps.newHashMap();
        String[] headArr = fields.split(",");
        List<String> headLs = Arrays.asList(headArr);
        if(CollectionUtil.isNotEmpty(dataList)){
            List<Map<String,String>> headResultList = Lists.newArrayList();
            List<List<Map<String,Object>>> dataResultList = Lists.newArrayList();
            headLs.stream().forEach( e -> {
                Map<String, String> mp = new HashMap<>();
                mp.put("label", translateLabel(e,columns));
                headResultList.add(mp);
            });
            map.put("headData", headResultList);
            for (Map<String, Object> mmp: dataList) {
                List<Map<String,Object>> tmpList = Lists.newArrayList();
                for (String column:headLs) {
                    Map<String,Object> mp = new HashMap<>();
                    mp.put("value", mmp.get(column));
                    mp.put(column, mmp.get(column));
                    mp.put("status",1);  //
                    tmpList.add(mp);
                }
                dataResultList.add(tmpList);
            }
            map.put("tableData", dataResultList);
        }
        rows.add(map);
        pageData.setRows(rows);
        return pageData;
    }

    private String translateLabel(String column,List<TMonitorColumns> columns) {
        Optional<TMonitorColumns> optional = columns.stream().filter(ta -> ta.getColumnName().equals(column)).findFirst();
        if(optional.isPresent()){
            return optional.get().getColumnLabel();
        }else{
            return column;
        }
    }

}
